const express=require('express');
const {sqlsConfig} = require('../sqlconfig.js')
const respository=require('./sql/respository')
const {QueryBuilder}=require('./sql/stmtbuild')
const log=require('./config/log4js').log
const routeContainer={
    authRouter:express.Router(),
    test:express.Router()
}
const authentication=key=>key;
const listHandler=async (req,res)=>{
    const sqls=QueryBuilder.buildListStmt(req.sqlsConfig,req.generateParams)
    log.debug('sqls:',sqls)
    const result=await respository.getList(sqls.sql,sqls.args,req.dbDrive)
    res.status(200).json(result)
}
const pageListHandler=async (req,res)=>{
    const sqls=QueryBuilder.buildPageStmt(req.sqlsConfig,req.generateParams)
    log.info('sqls:',sqls)
    const result=await respository.getPageList(sqls,req.dbDrive)
    res.status(200).json(result)
}
const modifyHandler=async (req,res)=>{
    const sqls=QueryBuilder.buildModiStmt(req.sqlsConfig,req.generateParams)
    log.info('sqls:',sqls)
    const result=await respository.exec(sqls.sql,sqls.args,req.dbDrive)
    res.status(200).json(result)
}
const generateParams=(req,res) => {
    const config = req.sqlsConfig??{};
    return config?.paramsMapping?.reduce(async (acc,  mapping) => {
      const value = req[mapping.source]?.[mapping.alias || mapping.field];
      // 参数验证 
      if (mapping.schema) {
        const result=await mapping?.schema?.validate(value)
        if (result?.error){
            res.status(400).json({code:1,msg:`参数${mapping.alias || mapping.field}的值${value}不符合规则：${result.error.details[0].message}`})
            throw new Error('VALIDATION_FAILED'); // 终止后续处理 
            
            }else{
                acc[mapping.field] = result.value
            }
      }else{
      if (value !== undefined) 
        acc[mapping.field] = result?.value || value;
      }
      return acc;
    }, { ...config.presetParams  });
  };
  
const commonMiddleware = async (req, res, next) => {
    const apikey=req.apiKey
    if (!apikey){
         next()
    }else{
      if (sqlsConfig?.[apikey]){
        req.dbDrive=sqlsConfig[apikey].dbDrive
        req.sqlsConfig=sqlsConfig[apikey]
        try{
        req.generateParams=await generateParams(req,res)
        next();
        }catch(e){
            log.warn({code:1,msg:e.message})
            // throw new Error(e.message);
            return null;
        }
        
        }else{
            res.json({code:3000,msg:`${apikey}:'无效的API调用'`})
        }
    }
  };
  routeContainer?.authRouter
  .use((req,  res, next) => {
    const start = process.hrtime(); 
    res.on('finish',  () => {
      const diff = process.hrtime(start);
      log.info(` ${req.url}请求耗时: ${diff[0] * 1e3 + diff[1] / 1e6}ms`);
    });
    next();
  })
  .use((req, res, next) => {
    if (req.url.startsWith('/api/v3/auth')  && !authentication(req.query.apiKey))  {
      return res.status(401).json({  code: 40101, msg: 'Unauthorized' });
    }
    next();
  })
  .all('/*/:apikey',(req,res,next)=>{
    req.apiKey=req.params['apikey'];
    res.status(200)
    next()})
  .use(commonMiddleware)
  .all('/list/:apikey',listHandler)
  .all('/page/:apikey',pageListHandler)
  .post('/modi/:apikey',modifyHandler)
  .get('/api',(req,res)=>{
    res.json({code:1})
  })
  routeContainer?.test
  .get('/api',(req,res)=>{
    res.json({code:1})
  })
  module.exports=exports={routeContainer};
